package compro.admission.form.dao;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import compro.admission.form.entity.Application;
import compro.admission.form.entity.Education;
import compro.admission.form.entity.EnglishProficiency;
import compro.admission.form.entity.PersonalInformaion;
import compro.admission.form.entity.Prerequisites;
import compro.admission.form.entity.SelfStudy;

import compro.admission.form.entity.ProfessionalExperience;

import compro.admission.form.entity.ProgrammingSkill;

import compro.admission.form.entity.User;

@Component
@Transactional(propagation = Propagation.MANDATORY)
public class ApplicationDAO {
	private SessionFactory sessionFactory;

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	@Resource
	@Transactional(propagation = Propagation.SUPPORTS)
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	/*-------------------------------------------------------------------
	 0. Application
	 -------------------------------------------------------------------*/
	public Application getApplicationById(long id) {
		return (Application) sessionFactory.getCurrentSession()
				.createQuery("FROM Application WHERE id = :id")
				.setParameter("id", id).uniqueResult();
	}

	public void saveApplication(Application application) {
		sessionFactory.getCurrentSession().persist(application);
	}

	@Transactional
	public void updateApplication(Application application) {
		sessionFactory.getCurrentSession().update(application);
	}

	public Application getApplication(User user) {
		if (user.getApplication() == null)
			return null;

		@SuppressWarnings("unchecked")
		List<Application> applicationList = sessionFactory.getCurrentSession()
				.createQuery("FROM Application WHERE id = :id")
				.setParameter("id", user.getApplication().getId()).list();
		if (applicationList.size() == 0) {
			return null;
		} else {
			return applicationList.get(0);
		}
	}

	/*-------------------------------------------------------------------
	 1. Personal Information
	 -------------------------------------------------------------------*/
	public void savePersonalInformaion(PersonalInformaion personalInformaion) {
		sessionFactory.getCurrentSession().persist(personalInformaion);
	}

	public void updatePersonalInformation(
			PersonalInformaion oldPersonalInformaion) {
		sessionFactory.getCurrentSession().update(oldPersonalInformaion);
	}

	public PersonalInformaion getPersonalInformation(Application application) {
		PersonalInformaion personalInformaion = null;
		if (application.getPersonalInformaion() != null) {
			personalInformaion = (PersonalInformaion) sessionFactory
					.getCurrentSession()
					.createQuery("from PersonalInformaion where id = :id")
					.setParameter("id",
							application.getPersonalInformaion().getId())
					.uniqueResult();
		}
		return personalInformaion;
	}

	/*-------------------------------------------------------------------
	 2. English Proficiency
	 -------------------------------------------------------------------*/
	public void saveEnglishProficiency(EnglishProficiency englishProficiency) {
		sessionFactory.getCurrentSession().persist(englishProficiency);
	}

	public void updateEnglishProficiency(EnglishProficiency englishProficiency) {
		sessionFactory.getCurrentSession().update(englishProficiency);
	}

	public EnglishProficiency getEnglishProficiency(Application application) {
		EnglishProficiency englishProficiency = null;
		if (application.getEnglishProficiency() != null) {
			englishProficiency = (EnglishProficiency) sessionFactory
					.getCurrentSession()
					.createQuery("from EnglishProficiency where id = :id")
					.setParameter("id",
							application.getEnglishProficiency().getId())
					.uniqueResult();
		}
		return englishProficiency;
	}

	/*-------------------------------------------------------------------
	 3. Education History
	 -------------------------------------------------------------------*/
	public void saveEducation(Education education) {
		sessionFactory.getCurrentSession().persist(education);
	}

	public void updateEducation(Education education) {
		sessionFactory.getCurrentSession().update(education);
	}

	public Education getEducation(Application application) {
		Education education = null;
		if (application.getEducation() != null) {
			education = (Education) sessionFactory.getCurrentSession()
					.createQuery("from Education where id = :id")
					.setParameter("id", application.getEducation().getId())
					.uniqueResult();
		}
		return education;
	}

	/*-------------------------------------------------------------------
	 4. Programming Skill
	 -------------------------------------------------------------------*/
	public void saveProgrammingSkill(ProgrammingSkill programmingSkill) {
		sessionFactory.getCurrentSession().persist(programmingSkill);
	}

	public void updateProgrammingSkill(ProgrammingSkill programmingSkill) {
		sessionFactory.getCurrentSession().update(programmingSkill);
	}

	public ProgrammingSkill getProgrammingSkill(Application application) {
		ProgrammingSkill programmingSkill = null;
		if (application.getProgrammingSkill() != null) {
			programmingSkill = (ProgrammingSkill) sessionFactory
					.getCurrentSession()
					.createQuery("from ProgrammingSkill where id = :id")
					.setParameter("id",
							application.getProgrammingSkill().getId())
					.uniqueResult();
		}
		return programmingSkill;
	}

	public ProfessionalExperience getProfessionalExperience(
			Application originalApplication) {
		ProfessionalExperience professionalExperience = null;
		if (originalApplication.getProfessionalExperience() != null) {
			professionalExperience = (ProfessionalExperience) sessionFactory
					.getCurrentSession()
					.createQuery("from ProfessionalExperience where id = :id")
					.setParameter(
							"id",
							originalApplication.getProfessionalExperience()
									.getId()).uniqueResult();
		}
		return professionalExperience;
	}

	public void saveProfessionalExperience(
			ProfessionalExperience professionalExperience) {
		sessionFactory.getCurrentSession().persist(professionalExperience);
	}

	public void updatePersonalInformation(
			ProfessionalExperience oldProfessionalExperience) {
		sessionFactory.getCurrentSession().update(oldProfessionalExperience);
	}

	/*-------------------------------------------------------------------
	 5. Prerequisite
	 -------------------------------------------------------------------*/

	/*-------------------------------------------------------------------
	 6. Professional Experience
	 -------------------------------------------------------------------*/

	/*-------------------------------------------------------------------
	 7. Self Study
	 -------------------------------------------------------------------*/
	public SelfStudy getSelfStudy(Application originalApplication) {
		SelfStudy selfStudy = null;
		if (originalApplication.getSelfStudy() != null) {
			selfStudy = (SelfStudy) sessionFactory
					.getCurrentSession()
					.createQuery("from SelfStudy where id = :id")
					.setParameter("id",
							originalApplication.getSelfStudy().getId())
					.uniqueResult();
		}
		return selfStudy;
	}

	public void saveSelfStudy(SelfStudy selfStudy) {
		sessionFactory.getCurrentSession().persist(selfStudy);
	}

	public void updateSelfStudy(SelfStudy oldSelfStudy) {
		sessionFactory.getCurrentSession().update(oldSelfStudy);
	}

	public Prerequisites getPrerequisites(Application originalApplication) {
		Prerequisites prerequisites = null;
		if (originalApplication.getPrerequisites() != null) {
			prerequisites = (Prerequisites) sessionFactory
					.getCurrentSession()
					.createQuery("from Prerequisites where id = :id")
					.setParameter("id",
							originalApplication.getPrerequisites().getId())
					.uniqueResult();
		}
		return prerequisites;
	}

	public void savePrerequisites(Prerequisites prerequisites) {
		sessionFactory.getCurrentSession().persist(prerequisites);
	}

	public void updateSelfStudy(Prerequisites oldPrerequisites) {
		sessionFactory.getCurrentSession().update(oldPrerequisites);
	}

}
